
CV.Tree.Draw = {

    getHTML: function(node) {

        var prefix = node.tree.DOMidPrefix;
        var checkbox = '';
        if(node.state.checked != null) {
            if(!node.hasCheckbox) {
                node.state.checked = 'nochecked';
            }
            checkbox = new Element('span.cv-tree-checkbox.cv-tree-node-' + node.state.checked + '[uid=' + node.UID + '][html=' + CV.Tree.Draw.zeroSpace + ']');
        }

        var copy = 'cv-tree-empty-icon', colorname = 'cv-tree-default';
        if(node.data) {
            copy = (node.data.copy ? '<b style="color:green;"> (copy)</b>' : '');

            switch(node.data.type) {
                case 'C':
                    node.openIcon  = 'cv-tree-folder-open-icon';
                    node.closeIcon = 'cv-tree-folder-close-icon';
                    colorname = 'cv-tree-category';
                    break;
                case 'P':
                    node.openIcon  = 'cv-tree-open-icon';
                    node.closeIcon = 'cv-tree-close-icon';
                    colorname = 'cv-tree-preference';
                    break;
                case 'A':
                    node.openIcon  = 'cv-tree-bin-open-icon';
                    node.closeIcon = 'cv-tree-bin-close-icon';
                    colorname = 'cv-tree-attribute';
                    break;
                default :
                    node.openIcon  = 'cv-tree-empty-icon';
                    node.closeIcon = 'cv-tree-empty-icon';
                    colorname = 'cv-tree-default';
            }
        }
        var tagname = new Element('span.cv-tree-name.' + colorname + '[uid=' + node.UID + '][html=' + node.name + copy + ']',{
            'events': {
                'contextmenu': this.contextmenu.bind(this, node)
            }
        });

        var gagetType = (node.data.type == 'A' ? 'none' : node.getGadjetType()); // if attribute no need plus
        //console.log('bef node=',node);
        var div = new Element('div#' + (prefix + node.UID) + '.cv-tree-node' + (node.isLast() ? '.cv-tree-node-last' : '') + '[style=' + (node.hidden ? 'display:none' : '') + ']');
        div.adopt(
            new Element('span.cv-tree-node-wrapper.' + node.cls + (node.state.selected ? '.cv-tree-node-selected' : '') + '[uid=' + node.UID + ']')
                .adopt(
                    new Element('span.cv-tree-gadjet.cv-tree-gadjet.cv-tree-gadjet-' + gagetType + '[uid=' + node.UID + '][html=' + CV.Tree.Draw.zeroSpace + ']'),
                    checkbox,
                    new Element('span.cv-tree-icon.' + node.closeIcon + '[uid=' + node.UID + '][html=' + CV.Tree.Draw.zeroSpace + ']'),
                    tagname
                ),
            new Element('div.cv-tree-children[style=display:none;]')
        );

        return div;
    },
    contextmenu: function(node, evt) {
        evt.stop();

        var cm = document.id('contextmenu');
        cm.adopt(
            new Element('li').adopt(
                new Element('a#rename[href=javascript:;][text=Rename]',{
                    'events': {
                        'click': this.clicked.bind(this, node)
                    }
                })
            ),
            new Element('li').adopt(
                new Element('a#add[href=javascript:;][text=Add new]',{
                    'events': {
                        'click': this.clicked.bind(this, node)
                    }
                })
            ),
            new Element('li').adopt(
                new Element('a#delete[href=javascript:;][text=Delete]',{
                    'events': {
                        'click': this.clicked.bind(this, node)
                    }
                })
            ),
            new Element('li').adopt(
                new Element('a#quit.separator[href=javascript:;][text=Quit]',{
                    'events': {
                        'click': this.clicked.bind(this, node)
                    }
                })
            )
        );
        cm.setStyles({
            'top': evt.page.y,
            'left': evt.page.x,
            'position': 'absolute',
            'z-index': '200'
        });
        cm.set('tween', {duration: 'long', property: 'opacity'});
        cm.get('tween').start(1);

        document.id(document.body).addEvent('click', function(evt) {
            evt.stop();
            cm.get('tween').start(0);
            cm.empty();
        });
    },
    clicked: function(node, evt) {

        var action = evt.target.get('id');
        switch(action) {
            case 'rename' :
                if(node) node.rename();
                break;
            case 'add':
                if(node) node.tree.add({property: {name: 'new - rename'}}, node, 'inside');
                break;
            case 'delete':
                if(confirm('delete?')) {
                    if(node) node.remove();
                }
                break;
        }
    },
    children: function(parent, container) {

        parent.open = true;
        parent.$draw = true;
        container = container || parent.getDOM('children');

        parent.children.each(function(child) {
            container.adopt(this.getHTML(child));
        }, this);

        parent.tree.fireEvent('drawChildren',[parent]);
    },
    root: function(tree) {
        this.tree = tree;
        var domRoot = this.node(tree.root);
        domRoot.inject(tree.wrapper);
        tree.$draw = true;
        tree.fireEvent('drawRoot');
    },
    forestRoot: function(tree) {
        this.tree = tree;
        var container = new Element('div.cv-tree-children-root').inject(tree.wrapper, 'inside');
        CV.Tree.Draw.children(tree.root, container);
    },
    node: function(node) {
        return new Element('div').adopt(this.getHTML(node)).getFirst();
    },
    isUpdatable: function(node){
        return ((!node || !node.tree) || (node.getParent() && !node.getParent().$draw) || (node.isRoot() && (!node.tree.$draw || node.tree.forest))) ? false : true;
    },
    update: function(node){
        if(!this.isUpdatable(node)) return null;
        if(!node.hasChildren()) node.state.open = false;

        node.getDOM('gadjet').className = 'cv-tree-gadjet cv-tree-gadjet-' + node.getGadjetType();
        if(node.closeIconUrl) {
            node.getDOM('icon').setStyle('background-image', 'url(' + (node.isOpen() ? node.openIconUrl : node.closeIconUrl) + ')');
        }
        else {
            if(node.data) {
                switch(node.data.type) {
                    case 'C':
                        node.openIcon  = 'cv-tree-folder-open-icon';
                        node.closeIcon = 'cv-tree-folder-close-icon';
                        break;
                    case 'P':
                        node.openIcon  = 'cv-tree-open-icon';
                        node.closeIcon = 'cv-tree-close-icon';
                        break;
                    case 'A':
                        node.openIcon  = 'cv-tree-bin-open-icon';
                        node.closeIcon = 'cv-tree-bin-close-icon';
                        break;
                    default :
                        node.openIcon  = 'cv-tree-empty-icon';
                        node.closeIcon = 'cv-tree-empty-icon';
                }
            }
            var icon = node.isOpen() ? node.openIcon : node.closeIcon;
            node.getDOM('icon').className = 'cv-tree-icon ' + icon;
        }
        node.getDOM('node')[(node.isLastVisible() ? 'add' : 'remove') + 'Class']('cv-tree-node-last');
        if(node.$loading) return null;

        var children = node.getDOM('children');
        if(node.isOpen()) {
            if(!node.$draw) CV.Tree.Draw.children(node);
            children.style.display = 'block';
        }
        else {
            children.style.display = 'none';
        }
        node.tree.fireEvent('updateNode', node);

        return node;
    },
    inject: function(node, element) {
        if(!this.isUpdatable(node)) return;

        element = element || node.getDOM('node') || this.node(node);
        var previous = node.getPrevious();

        if(previous) {
            element.inject(previous.getDOM('node'), 'after');
            return;
        }
        var container;
        if(node.tree.forest && node.parentNode.isRoot()){
            container = node.tree.wrapper.getElement('.cv-tree-children-root');
        }
        else if(node.tree.root == node) {
            container = node.tree.wrapper;
        }
        else {
            container = node.parentNode.getDOM('children');
        }
        element.inject(container, 'top');
    }
};

CV.Tree.Draw.zeroSpace = Browser.ie ? '&shy;' : (Browser.chrome ? '&#8203' : '');

